//Menu Constructor
function Menu(world,element) {
	this.World = world;
	this.Element = element;
	this.clear();
}

Menu.prototype.display = function() {
	var disp="";
	this.Element.innerHTML = disp;
}

Menu.prototype.justify = function(str,tot,dir) {
	var side=dir;
	if (side==0) side++; //Change to right if center
	while(str.length < tot) {
		if (side==-1) {
			str+=' ';
		} else {
			str=' '+str;
		}
		if (dir==0) side=0-side; //Switch the side if centering.
	}
	return str;
}

Menu.prototype.clear = function() {
	this.Selected = 1;
	this.Page = 0;
	this.Arr;
	this.inc = function() {return;};
	this.dec = function() {return;};
	this.ent = function() {return;};
}

Menu.prototype.setArr = function(arr) {
	this.Arr = arr;
}

Menu.prototype.update = function() {
	var disp="";
	disp+=this.justify(this.Arr["TT"],80,0)+"<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;"; // Lines 1 & 2
	if (!this.Arr["DSC"]) { //Lines 3 - 8
		disp+=this.Arr[this.Selected]["DSC"];
	} else {
		disp+=this.Arr["DSC"];
	}
	disp+="<br/>";
	for(var i=1;i<13;i++) {
		var ln =(this.Page*12+i);
		if (this.Arr["CNT"] < ln) {
			this.disp+="<br/>"; //Add a blank Line
		} else {
			if (ln==this.Selected) disp+="<b>&nbsp;-";
			else disp+="&nbsp;&nbsp;";
			if (this.Arr[ln]["CLR"]!="") disp+="<font color='"+this.Arr[ln]["CLR"]+"'>";
			for(var j=0;j<this.Arr["COL"];j++) {
				disp+="&nbsp;"+this.justify(this.Arr[ln][j],this.Arr[0][j][0],this.Arr[0][j][1]);
			}
			if (this.Arr[ln]["CLR"]!="") disp+="</font>";
			if (ln==this.Selected) disp+="&nbsp;-&nbsp;</b>";
			else disp+="&nbsp;&nbsp;&nbsp;";
		}
		disp+="<br/>";
	}
	this.Element.innerHTML = disp.replace(/ /gi,"&nbsp;").replace(/~/gi," "); //Update the display;
}

Menu.prototype.pageUp = function() {
	this.Page--;
	this.Selected-=12;
	if (this.Page<0) {
		this.Page=0;
		this.Selected=1; //If paging up on first page move selection to top.
	}
}

Menu.prototype.pageDown = function() {
	this.Page++;
	this.Selected+=12;
	if (this.Page*12+1 > this.Arr["CNT"]) {
		this.Page--;
	}
	if (this.Selected > this.Arr["CNT"]) this.Selected = this.Arr["CNT"]; //If paging down on the last page move selection to last.
}

Menu.prototype.up = function() {
	this.Selected--;
	if (this.Selected < 1) this.Selected = 1;
	if (this.Selected < (this.Page*12+1)) 
	{
		this.Selected+=12;
		this.pageUp();
	}
}

Menu.prototype.down = function() {
	this.Selected++;
	if (this.Selected > this.Arr["CNT"]) this.Selected = this.Arr["CNT"];
	if (this.Selected > ((this.Page+1)*12)) {
		this.Selected -= 12;
		this.pageDown();
	}
}

Menu.prototype.keyListener = function(key) {
	switch(key) {
		case '7':
			this.Selected=1;
			this.Page=0;
			break;
		case '1':
			this.Selected = this.Arr["CNT"];
			this.Page = (this.Arr["CNT"]-(this.Arr["CNT"]%12))/12;
			break;
		case '8':
			this.up();
			break;
		case '2':
			this.down();
			break;
		case '9':
			this.pageUp();
			break;
		case '3':
			this.pageDown();
			break;
		case String.fromCharCode(13):
			this.ent();
			break;
		case '+':
			this.inc();
			break;
		case '-':
			this.dec();
			break;
		case '0':
			if (this.exit()) {
				this.World.Flags=-1;
				this.World.Message.refreshLines();
				return;
			}
			break;
	}
	this.update();
}

Menu.prototype.newArr = function(tt) {
	var arr = [];
	arr["TT"]=tt;
	arr["CNT"]=0;
	arr["COL"]=0;
	arr[0] = [];
	return arr;
}

Menu.prototype.addColumn = function(arr,tot,j) {
	arr[0][arr["COL"]]=[];
	arr[0][arr["COL"]][0] = tot;
	arr[0][arr["COL"]][1] = j;
	arr["COL"]++;
	return arr;
}

Menu.prototype.addRow = function(arr,ret,row,desc) {
	arr["CNT"]++;
	arr[arr["CNT"]] = row.split(";");
	arr[arr["CNT"]]["RET"] = ret;
	if (desc != "") arr[arr["CNT"]]["DSC"] = desc;
	return arr;
}

Menu.prototype.mainMenu = function() {
	this.clear();
	var arr = this.newArr("Main Menu");
	arr["DSC"] = "This rogue-like is based loosely on the pen and paper RPG by Chris Morgan<br/> called Runebearer. If you wish to learn more visit <a~href='http://www.runebearer.com'~target='_blank'>www.runebearer.com</a>. More<br/> than a few of the gameplay mechanics required changes to fit into a<br/> rogue-like. As such i would encourage you to get a few friends together and<br/> try out Chris's version.<br/>";
	arr = this.addColumn(arr,74,0);
	arr = this.addRow(arr,"","New Game");
	arr = this.addRow(arr,"","Load Game");
	arr = this.addRow(arr,"","Save Game");
	this.ent = this.mainEnt;
	this.setArr(arr);
	this.update();
}

Menu.prototype.mainEnt = function() {
	switch(this.Selected) {
		case 1: //New
			this.World.newGame();
			break;
		case 2: //Load
			break;
		case 3: // Save
			break;
	}
}

Menu.prototype.mainExit = function() {
	return !!this.World.Player;
}

Menu.prototype.attributeExit = function() {
	return 1;
}

Menu.prototype.attributeMenu = function(n) {
	this.clear();
	this.World.Player.updateStats();
	if (n) this.Selected=n;
	var arr=this.newArr("Attributes");
	arr = this.addColumn(arr,54,-1)
	arr = this.addColumn(arr,20,1)
	if (this.World.Flags == 3) arr = this.addRow(arr,"R","Roll Stat Points;"+this.World.Player.Stats["FRE"],"You can re-roll your total assignable stat points. This will remove any that<br/> you have added to your stats.<br/><br/><br/><br/>");
	else arr=this.addRow(arr,"P","Purchase Stat Point;"+this.World.Player.Stats["FRE"],"You can purchase a extra stat point for 10 free checks. Increasing a stat<br/> after you have trained a skill will not increase the skill that it affects.<br/><br/><br/><br/>");
	if (this.World.Flags == 3) arr = this.addRow(arr,"?","Random Stats;?","You can roll random stats for your character. This is the closest you will<br/> get to pre-generated characters.<br/><br/><br/><br/>");
	arr = this.addRow(arr,"AGI","Agility;"+this.World.Player.Stats["AGI"],"Agility is the measure of how light on their feet your character is. Agility<br/> affects skills like dodging.<br/><br/><br/><br/>");
	arr = this.addRow(arr,"CHA","Charisma;"+this.World.Player.Stats["CHA"],"This is a mixture of the characters appearance and their personality.<br/> Characters with high charisma are natural leaders.<br/><br/><br/><br/>");
	arr = this.addRow(arr,"DEX","Dexterity;"+this.World.Player.Stats["DEX"],"Dexterity measures the hand-eye coordination of a character as well as their<br/> ability to do fine work with their hands. Affects the characters ability to<br/> hit with a weapon and pick locks.<br/><br/><br/>");
	arr = this.addRow(arr,"INT","Intelligence;"+this.World.Player.Stats["INT"],"Intelligence is the reasoning and learning ability of the character. It is<br/> an important skill for characters that will be relying on magic.<br/><br/><br/><br/>");
	arr = this.addRow(arr,"PER","Perception;"+this.World.Player.Stats["PER"],"Perception is the ability to hear and see the world around.<br/><br/><br/><br/><br/>");
	arr = this.addRow(arr,"SPD","Speed;"+this.World.Player.Stats["SPD"],"Speed measures the reaction time of a character and to a lessaer degree<br/> their foot speed. Some combat skills like knife rely on speed more than<br/> coordination.<br/><br/><br/>");
	arr = this.addRow(arr,"SPI","Spirit;"+this.World.Player.Stats["SPI"],"Spirit measures the character's ability to mold magical forces to his<br/> advantage.<br/><br/><br/><br/>");
	arr = this.addRow(arr,"STR","Strength;"+this.World.Player.Stats["STR"],"Strength determines the physical prowess of your character. Strength affects<br/> most of the weapon skills along with other general skills like swimming.<br/><br/><br/><br/>");
	arr = this.addRow(arr,"TOU","Toughness;"+this.World.Player.Stats["TOU"],"Toughness measures the ability of the character to take damage and resist<br/> poison and diseases. Toughness plays a part in determining HP.<br/><br/><br/><br/>");
	arr = this.addRow(arr,"WIL","Will;"+this.World.Player.Stats["WIL"],"Will measures the characters willpower. It is the ability to overcome fear<br/> or temptation.<br/><br/><br/><br/>");
	if (this.World.Flags == 3) arr = this.addRow(arr,"E","Reset Stats;-","This will reset your stats back into available points in case you want to<br/> drastically change the way that you were allocating your character. This<br/> option is only available at character creation.<br/><br/><br/>");
	this.exit = this.attributeExit;
	this.inc = this.attInc;
	this.dec = this.attDec;
	this.ent = this.attInc;
	this.setArr(arr);
	this.update();
}

Menu.prototype.attDec = function() {
	if (this.Arr[this.Selected]["RET"].length > 1) {
		if (this.World.Player.Stats[this.Arr[this.Selected]["RET"]] > 1) {
			this.World.Player.Stats[this.Arr[this.Selected]["RET"]]--;
			this.World.Player.Stats["FRE"]++;
		}
	}
	this.attributeMenu(this.Selected);
}

Menu.prototype.attInc = function() {
	if (this.Arr[this.Selected]["RET"].length == 1) {
		switch(this.Arr[this.Selected]["RET"]) {
			case "R":
				this.World.Player.resetStats();
				this.World.Player.Stats["FRE"] = this.World.Dice.roll(10,4,6,-5);
				break;
			case "P":
				if (this.World.Player.Attrb["FC"] >= 10) {
					this.World.Player.Attrb["FC"] -= 10;
					this.World.Player.Stats["FRE"]++;
				}
				break;
			case "E":
				this.World.Player.Stats["FRE"] = this.World.Player.resetStats();
				break;
			case "?":
				for (var STAT in this.World.Player.Stats) {
					if (STAT != "FRE") {
						this.World.Player.Stats[STAT] = this.World.Dice.roll(1,4,6,-4);
					} else {
						this.World.Player.Stats[STAT] = 0;
					}
				}
				break;
		}
	} else {
		if (this.World.Player.Stats["FRE"] > 0) {
			this.World.Player.Stats["FRE"]--;
			this.World.Player.Stats[this.Arr[this.Selected]["RET"]]++;
		}
	}
	this.attributeMenu(this.Selected);
}